import React, {FC, Key, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
import "./JournalPeriodList.less";
import * as API from "@/services";
import {useRequest} from "ahooks";
import {JournalDetailContext} from "@/pages/JournalPage/JournalDetail/commons/JournalDetailContext";
import {message, TreeDataNode} from 'antd';
import {Empty, Image, Spin, Tree} from "antd";
import default_art_cover from "@/assets/default_art_cover.png";
import HxIcon from "@/components/HxIcon";
import {HxArticleNormalItem} from "@/components/HxArticleItem";
import classNames from "classnames";
import useAuthedCheck from "@/components/hooks/UseAuthedCheck";
import HxLineCollapse from "@/components/HxLineCollapse";
import {useLocation} from '@umijs/max';
import {history} from "@@/exports";
import queryString from "query-string";
import lodash from "lodash";
import {correspVal} from "@/utils/biz";
import {HxConfigContext} from "@/layouts/HxConfigContext";
import {Journal_Summary} from "@/services";
import {JournalPeriodItem} from "@/pages/JournalPage/JournalDetail/commons/JournalPeriodItem";
import HxPagination from "@/components/HxPagination";
import {FormattedMessage} from "umi";
import useBreakpoint from "antd/es/grid/hooks/useBreakpoint";
import HxFlexibleArticleGrid from '@/pages/SearchPage/common/HxFlexibleArticleGrid';

export type JournalPeriodDisplayType = "tree" | "card";
type PeriodTreeDataNode = TreeDataNode & {
  year?: string | number;
}

interface JournalPeriodListProps {
  expandFirst?: boolean;
}


/**
 * 期刊分期 页面
 */
const JournalPeriodList: FC<JournalPeriodListProps> = (props) => {
  const {journalId, journal} = useContext(JournalDetailContext)
  const location = useLocation();
  const screens = useBreakpoint();
  const isMobile = !(screens.lg || screens.xxl || screens.xl);

  const {expandFirst = true} = props;
  const {journalPeriodDisplayType = "card"} = useContext(JournalDetailContext);

  const activeKeyInitialized = useRef(false);
  const [activeKey, setActiveKey] = useState<Key[]>([])
  const [itemsMap, setItemsMap] = useState<Record<string, API.FrontJournalPeriod[]>>({})

  const authedCheck = useAuthedCheck();

  //从请求params中获取选中的期
  const selectedPeriodId: string | undefined = useMemo(() => {
    const {periodId} = queryString.parse(location?.search);
    let ret = lodash.isArray(periodId) ? periodId[0] : periodId;
    if (!periodId) {
      ret = null;
    }
    return ret || undefined;
  }, [location?.search]);

  const statsReq = useRequest(() => API.queryFrontJournalPeriodYearStat(journalId!), {
    refreshDeps: []
  });

  const periodReq = useRequest(() => API.queryFrontJournalPeriod(selectedPeriodId!), {
    ready: !!selectedPeriodId,
    refreshDeps: [selectedPeriodId]
  });

  const additionalQuery = useMemo(() => {
    return {
      hotType: "CREATE_TIME",
      periodIds: selectedPeriodId,
      journalId: journalId,
    }
  }, [journalId, selectedPeriodId]);


  const stats = statsReq.data?.data || [];
  const period = periodReq.data?.data || undefined;


  useEffect(() => {
    if (activeKey.length === 0 && stats.length > 0) {
      if (!!selectedPeriodId) {
        if (!!period) {
          setActiveKey([`${period.year}`])
        }
      } else if (!activeKeyInitialized.current && expandFirst) {
        setActiveKey([`${stats[0].year}`])
      }
      activeKeyInitialized.current = true;
    }
  }, [stats, selectedPeriodId, period]);

  useEffect(() => {
    if (!selectedPeriodId && Object.keys(itemsMap).length > 0) {
      const firstKey = Object.keys(itemsMap)[0];
      const firstValue = itemsMap[firstKey];
      if (firstValue?.length > 0) {
        /*if (!activeKey.includes(firstKey)) {
          setActiveKey([...activeKey, firstKey])
        }*/
        history.push({
          pathname: ``,
          search: queryString.stringify({
            ...queryString.parse(location.search),
            periodId: firstValue[0].id,
          })
        });
      }
    }
  }, [itemsMap, location?.search]);


  useEffect(() => {
    const process = async () => {
      if (activeKey.length > 0) {
        for (const k of activeKey) {
          const items = itemsMap[`${k}`];
          if (!items) {
            const resp = await API.queryFrontJournalPeriods({journalId, year: Number(k), pageSize: 1000});
            itemsMap[`${k}`] = resp.data || [];
          }
          setItemsMap({...itemsMap})
        }
      }
    };
    process();
  }, [activeKey]);

  const handlePeriodIdSelected = useCallback((periodId: API.EntityId, year?: string | number) => {
    if (!!year && !activeKey.includes(year)) {
      setActiveKey([...activeKey, year])
    }
    history.push({
      pathname: ``,
      search: queryString.stringify({
        ...queryString.parse(location.search),
        periodId: periodId,
        periodDisplayType: "tree"
      })
    });
  }, [activeKey, location.search]);


  const collapseItems = useMemo(() => {
    if (journalPeriodDisplayType === "card") {
      return stats.map(stat => {
        const key = `${stat.year}`;
        const items = itemsMap[key]
        return {
          key: key,
          label: (
            <div className={"jp-collapse-year-item-header"}>
              <div className={"jp-collapse-year-item-title"}>
                <FormattedMessage id="journal.period-info.aggregate-by-year-desc" values={{year: stat.year}}/>
              </div>
              <div className={"jp-collapse-year-item-tj"}>
                <FormattedMessage id="journal.period-info.aggregate-by-issue-desc" values={{total: stat.periodNum}}/>
              </div>
            </div>
          ),
          children: <div className={"jp-collapse-items"}>
            {items?.map(item => (
              <JournalPeriodItem
                key={item.id}
                item={item}
                journal={journal}
                onClick={() => handlePeriodIdSelected(item.id, item.year)}
                onJournalPeriodChange={(item) => {
                  itemsMap[`${stat.year}`] = itemsMap[`${stat.year}`].map(d => {
                    if (d.id === item.id) {
                      return {
                        ...item,
                      }
                    }
                    return d;
                  })
                  setItemsMap({...itemsMap})
                }}
              />
            ))}
          </div>
        }
      })
    }
    return [];
  }, [stats, itemsMap, journalPeriodDisplayType]);


  const treeItems = useMemo(() => {
    if (journalPeriodDisplayType === "tree") {
      return stats.map(stat => {
        const key: React.Key = `${stat.year}`;
        const items = itemsMap[key]
        return {
          key: key,
          title: <FormattedMessage id="journal.period-info.aggregate-by-year-desc" values={{year: stat.year}}/>,
          selectable: false,
          isLeaf: false,
          children: items?.map(item => {
            return {
              key: `${item.id}` as React.Key,
              //title: `${item.periodName}`,
              title: <FormattedMessage id="journal.period-info.period-desc" values={{year: stat.year, volume: item.volume, period: item.period}}/>,
              year: `${stat.year}`,
              icon: (
                <a onClick={(e) => {
                  e.preventDefault();
                  e.stopPropagation();
                  authedCheck(() => {
                    API.fav("period", item!.id, !!item?.hascollection).then(resp => {
                      if (resp.flag) {
                        message.success(!item?.hascollection ? "收藏成功" : "已取消收藏");
                        itemsMap[`${stat.year}`] = itemsMap[`${stat.year}`].map(d => {
                          if (d.id === item.id) {
                            return {
                              ...item,
                              hascollection: !item?.hascollection,
                            }
                          }
                          return d;
                        })
                        setItemsMap({...itemsMap})
                      }
                    })
                  })

                }}>
                  <HxIcon type={!!item?.hascollection ? "hxicon-shoucang-yishoucang" : "hxicon-shoucang"}/>
                </a>
              ),
              isLeaf: true,
            }
          })
        } as PeriodTreeDataNode;
      })
    }
    return [];
  }, [stats, itemsMap, journalPeriodDisplayType]);


  return (
    <div className={"journal-period-list-container"}>
      {
        journalPeriodDisplayType === "card" && (
          <div className={"journal-period-card-list-container"}>
            <HxLineCollapse
              className={"jp-collapse"}
              activeKey={activeKey as string[]}
              onChange={setActiveKey}
              ghost
              items={collapseItems}/>
          </div>
        )
      }
      {
        journalPeriodDisplayType === "tree" && (
          <div className={"journal-period-tree-list-container"}>
            <div className={"journal-period-tree-wrapper"}>
              <Tree<PeriodTreeDataNode>
                showIcon={true}
                expandedKeys={activeKey}
                onExpand={(keys) => setActiveKey(keys)}
                onSelect={(keys, t) => {
                  const year = t.node?.year;
                  handlePeriodIdSelected(t.node?.key as string, year)
                }}
                selectedKeys={selectedPeriodId ? [selectedPeriodId] : []}
                treeData={treeItems}
              />
            </div>
            <div className={classNames("journal-period-article-list",
              //{"journal-period-article-list-empty": articles.length === 0}
            )}>
              <HxFlexibleArticleGrid
                additionalQuery={additionalQuery}
                showEggs={false}
              />
            </div>
          </div>
        )
      }

    </div>
  );
};

export default JournalPeriodList;
